package com.dongzili.easysearch.common.base;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dongzili.easysearch.common.mybatisplus.MybatisPlusUtil;
import com.dongzili.easysearch.common.utils.ReflectUtils;
import com.dongzili.easysearch.common.vo.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class BaseController<T> {

    private final Class<T> tClass;
//    protected final BaseMapper<T> baseMapper;
    public BaseController(){
        this.tClass = resolveEntityClass();
//        DS ds = tClass.getAnnotation(DS.class);
//        if (ds != null){
//            DynamicDataSourceContextHolder.push(ds.value());
//        }else{
//            DynamicDataSourceContextHolder.push("main");
//        }
//        baseMapper = MybatisPlusUtil.getMapper(this.tClass);
    }
    /**
     * 列表查询
     */
    @PostMapping("/list")
    public R<List<T>> list(@RequestBody PageRequest<T> request) {
        QueryWrapper<T> query = new QueryWrapper<>(request.getEntity());
        // like 字段用 or 连接
        Map<String, Object> fieldValueMap = ReflectUtils.getNotNullFieldValueMap(request.getLikeEntity());
        if (!fieldValueMap.isEmpty()){
            query.and(m -> {
                fieldValueMap.forEach((k, v)->{
                    if (LogicType.Or.equals(request.getLikeLogicType())){
                        if(v instanceof String){
                            m.or().like(k, v);
                        }
                        else if (v instanceof List){
                            for (Object o : (List<?>) v) {
                                m.or().like(k, o);
                            }
                        }else {
                            m.or().eq(k, v);
                        }
                    }else{
                        if(v instanceof String){
                            m.like(k, v);
                        }
                        else if (v instanceof List){
                            for (Object o : (List<?>) v) {
                                m.like(k, o);
                            }
                        }else {
                            m.eq(k, v);
                        }
                    }

                });
            });
        }
        if (request.getIn() != null && !request.getIn().isEmpty()){
            request.getIn().forEach(query::in);
        }
        if (request.getNotIn() != null && !request.getNotIn().isEmpty()){
            request.getNotIn().forEach(query::notIn);
        }

        // 时间范围过滤
        addPeriodByCondition(request, query);
        // 排序字段
        addOrderByCondition(request, query);

        IPage<T> pageData = MybatisPlusUtil.getMapper(this.tClass).selectPage(new Page<>(request.getCurrent(), request.getSize()), query);
        return R.success(pageData.getRecords(), pageData.getTotal());
    }

//    /** 添加 */
//    @PostMapping("/add")
//    public R<Integer> add(@RequestBody T entity) {
//
//        Map<String, Object> fieldValueMap = new HashMap<>();
//        if (StpUtil.isLogin()){
//            User user = UserHelper.getCurrentUser();
//            fieldValueMap.put("creatorId", user.getId());
//            fieldValueMap.put("creatorName", user.getUsername());
//            fieldValueMap.put("modifierId", user.getId());
//            fieldValueMap.put("modifierName", user.getUsername());
//        }else{
//            fieldValueMap.put("creatorId", 0);
//            fieldValueMap.put("creatorName", "");
//            fieldValueMap.put("modifierId", 0);
//            fieldValueMap.put("modifierName", "");
//        }
//        try{
//            ReflectUtils.setValue(entity, fieldValueMap);
//        }catch (Exception e){
//            e.printStackTrace();
//        }
//        if(MybatisPlusUtil.getMapper(this.tClass).insert(entity) > 0){
//            return R.success();
//        }
//        return R.error();
//    }
//
//    /** 更新 */
//    @PostMapping("/update")
//    public R<Integer> update(@RequestBody T entity){
//        Map<String, Object> fieldValueMap = new HashMap<>();
//        if (StpUtil.isLogin()){
//            User user = UserHelper.getCurrentUser();
//            fieldValueMap.put("modifierId", user.getId());
//            fieldValueMap.put("modifierName", user.getUsername());
//        }else{
//            fieldValueMap.put("modifierId", 0);
//            fieldValueMap.put("modifierName", "");
//        }
//        try{
//            ReflectUtils.setValue(entity, fieldValueMap);
//        }catch (Exception e){
//            e.printStackTrace();
//        }
//
//        if(MybatisPlusUtil.getMapper(this.tClass).updateById(entity) > 0){
//            return R.success();
//        }else{
//            if (ReflectUtils.getPrimaryValue(entity) != null){
//                User user = UserHelper.getCurrentUser();
//                fieldValueMap.put("creatorId", user.getId());
//                fieldValueMap.put("creatorName", user.getUsername());
//                try{
//                    ReflectUtils.setValue(entity, fieldValueMap);
//                }catch (Exception e){
//                    e.printStackTrace();
//                }
//                if(MybatisPlusUtil.getMapper(this.tClass).insert(entity) > 0){
//                    return R.success();
//                }
//            }
//        }
//
//        return R.error();
//    }

    /** 根据id删除 */
    @GetMapping("/delete")
    public R<Integer> delete(@RequestParam("id") Integer id){
        if(MybatisPlusUtil.getMapper(this.tClass).deleteById(id) > 0){
            return R.success();
        }
        return R.error();
    }
    /** 根据id查询 */
    @GetMapping("/get")
        public R<T> get(@RequestParam("id") Integer id){
        return R.success(MybatisPlusUtil.getMapper(this.tClass).selectById(id));
    }

    private Class<T> resolveEntityClass() {
        Type superClass = getClass().getGenericSuperclass();
        if (superClass instanceof ParameterizedType) {
            ParameterizedType parameterizedType = (ParameterizedType) superClass;
            Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
            return (Class<T>) actualTypeArguments[0];
        }
        throw new IllegalArgumentException("Class is not parameterized with generic types");
    }

    /**
     * 添加排序条件
     */
    private static <T> void addOrderByCondition(PageRequest<T> request, QueryWrapper<T> queryWrapper) {
        if(request.getOrders()!=null && !request.getOrders().isEmpty()){
            for (OrderVo orderVo : request.getOrders()){
                if(OrderType.Desc.equals(orderVo.getOrderType())){
                    queryWrapper.orderByDesc(orderVo.getFiledName());
                }else{
                    queryWrapper.orderByAsc(orderVo.getFiledName());
                }
            }
        }
    }

    private static <T> void addPeriodByCondition(PageRequest<T> request, QueryWrapper<T> queryWrapper) {
        if(request.getQueryPeriod() != null && !request.getQueryPeriod().isEmpty()){
            for (Map.Entry<String, QueryPeriodVo> entry : request.getQueryPeriod().entrySet()){
                if (entry.getValue().getStartTime() != null && entry.getValue().getEndTime() != null){
                    queryWrapper.between(entry.getKey(), entry.getValue().getStartTime(), entry.getValue().getEndTime());
                }
            }
        }
    }

}
